package org.utils.thread;

import org.apache.log4j.Logger;
import org.utils.common.EnhancedException;
import org.utils.common.InitException;
import org.utils.util.Statistics;
import org.utils.util.StringUtils;
import org.utils.xml.XMLConfigurable;
import org.utils.xml.XMLDataNode;

/**
 * @author Manuel EVENO
 * @version 1.0
 */
public abstract class AbstractObjectManager extends Thread implements XMLConfigurable, Statistics
{
  private static int globalObjectHandledCount = 0;
  protected ExecutionContext context = null;
  protected Queue queue = null;
  protected int objecthandled = 0;

  protected Logger logger;

  public AbstractObjectManager()
  {
    super();
  }

  public void run()
  {
      while (! context.getStopStatus())
      {
		try
		{
		  Object item = queue.get();
		  logger.debug("Execution Context Stop Status:"+context.getStopStatus());
		  if (item == null)
		    continue ;
		  objecthandled++;
		  incrementGlobalHandledObjectCount();
		  handleObject(item);
		  logger.debug("Execution Context Stop Status:"+context.getStopStatus());
		}
		catch (QueueReadException e)
		{
		  Logger.getLogger(this.getClass()).warn(e.getMessage(), e);
		}
		catch (Exception e)
		{
		  Logger.getLogger(this.getClass()).error(e.getMessage(), e);
		}
      }
    logger.info("Is Exiting");
  }

  public void configure(XMLDataNode config) throws InitException
  {
    logger = Logger.getLogger(getClass());
    if (config.getAttribute("name") != null)
    	setName(config.getAttribute("name"));
  }
  /**
   * Increment the global handled Object count (count for all the threads)
   */
  public synchronized static void incrementGlobalHandledObjectCount()
  {
    globalObjectHandledCount++;
  }
  /**
   * Returns the global handled Object count (count for all the threads)
   * @return int
   */
  public static int getGlobalHandledObjectCount()
  {
    return globalObjectHandledCount;
  }
  /**
   * Resets the global handled Object count (reset for all the threads)
   */
  public static void resetGlobalHandledObjectCount()
  {
    globalObjectHandledCount = 0;
  }
  /**
   * Returns the handled Object count for this thread
   * @return int
   */
  public int getHandledObjectCount()
  {
    return objecthandled;
  }
  /**
   * Resets the handled Object count for this thread
   */
  public void resetHandledObjectCount()
  {
    objecthandled = 0;
  }
  /**
   * This method is call for each object handled by this thread.
   * You must inherit and define this method to make your own treatment.
   */
  protected abstract void handleObject(Object item) throws EnhancedException;

  public void setExecutionContext(ExecutionContext pContext)
  {
    this.context = pContext;
  }
  public void setQueue(Queue pQueue)
  {
    this.queue = pQueue;
  }
  public void getStatistics(StringBuffer buffer)
  {
  	buffer.append('[').append(getName()).append("] is ").append( isAlive() ? "alive" : "dead" );
	buffer.append(" (").append(getHandledObjectCount()).append(" objects handled)").append(StringUtils.newLine());
  }
}